package com.qingcheng.timer;

import com.qingcheng.dao.SeckillGoodsMapper;
import com.qingcheng.pojo.seckill.SeckillGoods;
import com.qingcheng.util.DateUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import tk.mybatis.mapper.entity.Example;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.Set;

@Component
public class SeckillGoodsPushTask {

    @Autowired
    private SeckillGoodsMapper seckillGoodsMapper;

    @Autowired
    private RedisTemplate redisTemplate;

    /**
     * 每30秒执行一次
     */
    @Scheduled(cron = "0/30 * * * * ?")//:从每分钟的第0秒开始执行，每过30秒执行一次
    public void loadGoodsPushRedis() {
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        System.out.println(simpleDateFormat.format(new Date()));
        //1.查询所有时间区间
        List<Date> dateMenus = DateUtil.getDateMenus();
        //2. 循环时间区间,查询每个时间区间的秒杀商品
        for (Date startTime : dateMenus) {
            Example example = new Example(SeckillGoods.class);
            Example.Criteria criteria = example.createCriteria();
            //2.1    商品必须审核通过
            criteria.andEqualTo("status", "1");

            //2.2    库存>0
            criteria.andGreaterThan("stockCount", 0);

            //2.3    秒杀开始时间>=当前循环的时间区间的开始时间
            criteria.andGreaterThanOrEqualTo("startTime", startTime);

            //2.4    秒杀结束时间<当前循环的时间区间的开始时间+2小时
            criteria.andLessThan("endTime", DateUtil.addDateHour(startTime, 2));

            //2.5    过滤redis中已经存在的该区间的秒杀商品
            Set keys = redisTemplate.boundHashOps("SeckillGoods_" + DateUtil.date2Str(startTime)).keys();
            if (keys != null && keys.size() > 0) {
                //select * from table where id not in (keys)
                criteria.andNotIn("id", keys);
            }

            //2.5   执行查询
            List<SeckillGoods> seckillGoods = seckillGoodsMapper.selectByExample(example);

            System.out.println(simpleDateFormat.format(startTime) + "共查询到商品" + seckillGoods.size());

            //3. 将秒杀商品存入Redis缓存
            for (SeckillGoods seckillGood : seckillGoods) {
                redisTemplate.boundHashOps("SeckillGoods_" + DateUtil.date2Str(startTime)).put(seckillGood.getId(), seckillGood);

                //剩余库存,加入队列
                Long[] ids = pushIds(seckillGood.getStockCount(), seckillGood.getId());
                //创建队列
                redisTemplate.boundListOps("SeckillGoodsCountList_" + seckillGood.getId()).leftPushAll(ids);
                //自增计数器
                redisTemplate.boundHashOps("SeckillGoodsCount").increment(seckillGood.getId(), seckillGood.getStockCount());
            }
        }
    }


    /***
     *  将商品ID存入到数组中
     *  @param len:长度
     *  @param id :值
     *  @return
     */
    public Long[] pushIds(int len, Long id) {
        Long[] ids = new Long[len];
        for (int i = 0; i < ids.length; i++) {
            ids[i] = id;
        }
        return ids;
    }

}
